package com.zscat.mallplus.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zscat.mallplus.annotation.IgnoreAuth;
import com.zscat.mallplus.core.LockInfo;
import com.zscat.mallplus.dms.entity.DmsOrder;
import com.zscat.mallplus.dms.service.IDeviceService;
import com.zscat.mallplus.dms.service.IDeviceTaskService;
import com.zscat.mallplus.dms.service.IDmsOrderService;
import com.zscat.mallplus.dms.service.IQsgStoreService;
import com.zscat.mallplus.enums.TaskType;
import com.zscat.mallplus.qsg.*;
import com.zscat.mallplus.qsg.impl.MqttConfigService;
import com.zscat.mallplus.ums.entity.UmsMember;
import com.zscat.mallplus.utils.CommonResult;
import com.zscat.mallplus.utils.HttpClientUtil;
import com.zscat.mallplus.utils.UserUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * 网关设备管理Controller
 */
@RestController
@Api(tags = "QsgGatewayDeviceController", description = "网关设备管理")
@RequestMapping("/api/gatewayDevice")
@Slf4j
public class QsgGatewayDeviceController {

    @Autowired
    private MqttConfigService mqttConfigService;
    @Autowired
    private IGatewayDeviceService gatewayDeviceService;
    @Autowired
    private IQsgGatewayInfoService gatewayInfoService;
    @Autowired
    private IDmsOrderService orderService;
    @Autowired
    private IDeviceService deviceService;
    @Autowired
    private IDeviceTaskService taskService;
    @Autowired
    private IQsgStoreService storeService;

    @IgnoreAuth
    @PostMapping(value = "/list")
    @ApiOperation(value = "网关设备列表")
    public Object list(Long deviceId, Integer storeId) {
        try {
            QueryWrapper qw = new QueryWrapper();
            qw.eq("device_id", deviceId);
            qw.eq("store_id", storeId);
            qw.orderByDesc("is_door");
            List<QsgGatewayDevice> gatewayDevices = gatewayDeviceService.list(qw);
            return new CommonResult().success(gatewayDevices);
        } catch (Exception e) {
            e.printStackTrace();
            return new CommonResult().failed();
        }
    }


    @IgnoreAuth
    @GetMapping(value = "/h5List")
    @ApiOperation(value = "网关设备列表")
    public Object h5List(@RequestParam Long deviceId, @RequestParam Integer storeId) {
        try {
            QueryWrapper qw = new QueryWrapper();
            qw.eq("device_id", deviceId);
            qw.eq("store_id", storeId);
            qw.orderByDesc("is_door");
            List<QsgGatewayDevice> gatewayDevices = gatewayDeviceService.list(qw);
            return new CommonResult().success(gatewayDevices);
        } catch (Exception e) {
            e.printStackTrace();
            return new CommonResult().failed();
        }
    }


    @IgnoreAuth
    @PostMapping(value = "/operate")
    @ApiOperation(value = "网关设备列表")
    public Object operate(Long gatewayDeviceId, int type, Long orderId) {
        try {
            UmsMember currentMember = UserUtils.getCurrentMember();
            QsgGatewayDevice gatewayDevice = gatewayDeviceService.getById(gatewayDeviceId);
            QsgGatewayInfo gatewayInfo = gatewayInfoService.getById(gatewayDevice.getGatewayId());
            DmsOrder order = orderService.getById(orderId);
            QsgDevice device = deviceService.getById(order.getDeviceId());
            if (gatewayDevice.getIsDoor() == 1 && type == 0) {
                order.setOpenStatus(1);
                orderService.updateById(order);
                //查询该笔订单是否存在时间任务
                QueryWrapper timeQw = new QueryWrapper();
                timeQw.eq("order_sn", order.getOrderSn());
                timeQw.eq("device_id", device.getId());
                List<QsgDeviceTask> tasks = taskService.list(timeQw);
                if (null == tasks || tasks.size() == 0) {
                    //没有该笔订单生成的时间任务，则生成
                    QsgDeviceTask timeTask = new QsgDeviceTask();
                    timeTask.setUpdateReason("网关点击开门生成");
                    timeTask.setUpdateTime(new Date());
                    timeTask.setMemberId(currentMember.getId().intValue());
                    timeTask.setCreateDatetime(new Date());
                    timeTask.setDeviceId(device.getId());
                    timeTask.setDeviceCode(device.getDeviceCode());
                    timeTask.setOrderSn(order.getOrderSn());
                    String endTime = order.getEndTime();
                    Date date = new Date(endTime);
                    timeTask.setEndTime(date);
                    timeTask.setTaskType(TaskType.GATEWAY_END_REPORT.getValue());
                    taskService.save(timeTask);//结束任务
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(date);
                    calendar.add(Calendar.MINUTE, -10);
                    timeTask.setEndTime(calendar.getTime());
                    timeTask.setTaskType(TaskType.GATEWAY_TEN_REPORT.getValue());
                    taskService.save(timeTask);//结束前10分钟

                    Calendar calfiveminute = Calendar.getInstance();
                    calfiveminute.setTime(date);
                    calfiveminute.add(Calendar.MINUTE, -5);
                    timeTask.setEndTime(calfiveminute.getTime());
                    timeTask.setTaskType(TaskType.GATEWAY_FIVE_MINUTE_REPORT.getValue());
                    taskService.save(timeTask);//结束前5分钟

                    Calendar calhalfhour = Calendar.getInstance();
                    calhalfhour.setTime(date);
                    calhalfhour.add(Calendar.MINUTE, -30);
                    timeTask.setEndTime(calhalfhour.getTime());
                    timeTask.setTaskType(TaskType.GATEWAY_HALF_HOUR_REPORT.getValue());
                    taskService.save(timeTask);//结束前30分钟

//                    Calendar current = Calendar.getInstance();
//                    current.add(Calendar.SECOND, 30);
//                    timeTask.setEndTime(current.getTime());
//                    timeTask.setTaskType(TaskType.GATEWAY_DELAY_CLOSEDOOR_REPORT.getValue());
//                    taskService.save(timeTask);//延迟30秒关门任务
                }
            } else {
                QueryWrapper timeQw = new QueryWrapper();
                timeQw.eq("order_sn", order.getOrderSn());
                timeQw.eq("device_id", device.getId());
                List<QsgDeviceTask> tasks = taskService.list(timeQw);
                if (null == tasks || tasks.size() == 0) {
                    return new CommonResult().success(1);
                }
            }
            //如果是wifi锁的开锁
            if ((2 == device.getDeviceType().intValue()) && gatewayDevice.getIsDoor() == 1 && type == 0) {
                sendWifiLockMsg(device);
                operateGatewayDeivce(gatewayDevice, gatewayInfo, type);
            } else {
                operateGatewayDeivce(gatewayDevice, gatewayInfo, type);
            }
            return new CommonResult().success();
        } catch (Exception e) {
            e.printStackTrace();
            return new CommonResult().failed();
        }
    }


    @IgnoreAuth
    @GetMapping(value = "/h5Operate")
    @ApiOperation(value = "后台网关设备操作")
    public Object h5Operate(Long gatewayDeviceId, int type) {
        try {
            QsgGatewayDevice gatewayDevice = gatewayDeviceService.getById(gatewayDeviceId);
            QsgGatewayInfo gatewayInfo = gatewayInfoService.getById(gatewayDevice.getGatewayId());
            QsgDevice device = deviceService.getById(gatewayDevice.getDeviceId());
            //如果是wifi锁的开启
            if ((2 == device.getDeviceType().intValue()) && gatewayDevice.getIsDoor() == 1 && type == 0) {
                sendWifiLockMsg(device);
                operateGatewayDeivce(gatewayDevice, gatewayInfo, type);
            } else {
                if(3 == device.getDeviceType().intValue() && gatewayDevice.getIsDoor() == 1 && type == 0){
                    operateGatewayLock(gatewayDevice,gatewayInfo,type);
                }else{
                    operateGatewayDeivce(gatewayDevice, gatewayInfo, type);
                }
            }
            return new CommonResult().success();
        } catch (Exception e) {
            e.printStackTrace();
            return new CommonResult().failed();
        }
    }

    /**
     * 后台网关保洁开门
     *
     * @return
     */
    @IgnoreAuth
    @GetMapping(value = "/task/openAllGWDevice")
    @ApiOperation(value = "后台网关设备临时开门")
    public Object openAllGWDevice(Long deviceId) {
        QsgDevice device = deviceService.getById(deviceId);
        QsgStore store = storeService.getById(device.getStoreId());
        //设备是离线状态
        Date expireTime = store.getSimOutTime();
        Date currentDate = new Date();
        if(1 == device.getOlStatus() || expireTime.before(currentDate)){
            return new CommonResult().success("设备离线");
        }
        QueryWrapper qw = new QueryWrapper();
        qw.eq("device_id",deviceId);
        qw.eq("store_id",store.getId());
        List<QsgGatewayDevice> gatewayDevices = gatewayDeviceService.list(qw);
        for (QsgGatewayDevice gdevice: gatewayDevices
        ) {
            Long gatewayId = gdevice.getGatewayId();
            QsgGatewayInfo gatewayInfo = gatewayInfoService.getById(gatewayId);
            try{
                if(gdevice.getIsDoor() == 1 && 3 == device.getDeviceType().intValue()){
                    JSONObject data = new JSONObject();
                    data.put("CommandId", UUID.randomUUID().toString());
                    data.put("SystemCode", "csqsg");
                    data.put("GatewayIeee", gatewayInfo.getSerialno());
                    data.put("SensorIeee", device.getDeviceCode());
                    data.put("Command","UnlockDoor");
                    data.put("PINCode","1809598");
                    mqttConfigService.publish("/toGW/" + gatewayInfo.getMacAddr(), data.toJSONString());
                }else if(gdevice.getIsVoice() == 1){
                    continue;
                }
                else{
                    operateGatewayDeivce(gdevice,gatewayInfo,0);
                }
            }catch (Exception e){
                log.error("开启网关设备失败.异常:{}",e.getMessage());
                return new CommonResult().failed("开启网关设备失败");
            }
        }
        return new CommonResult().success();
    }

    /**
     * 后台网关设备打扫完毕
     *
     * @return
     */
    @IgnoreAuth
    @GetMapping(value = "/task/closeAllGWDevice")
    @ApiOperation(value = "后台网关设备打扫完毕")
    public Object closeAllGWDevice(Long deviceId) {
        QsgDevice device = deviceService.getById(deviceId);
        QsgStore store = storeService.getById(device.getStoreId());
        //设备是离线状态
        Date expireTime = store.getSimOutTime();
        Date currentDate = new Date();
        if(1 == device.getOlStatus() || expireTime.before(currentDate)){
            return new CommonResult().success("设备离线");
        }
        QueryWrapper qw = new QueryWrapper();
        qw.eq("device_id",deviceId);
        List<QsgGatewayDevice> gatewayDevices = gatewayDeviceService.list(qw);
        for (QsgGatewayDevice gdevice: gatewayDevices
        ) {
            Long gatewayId = gdevice.getGatewayId();
            QsgGatewayInfo gatewayInfo = gatewayInfoService.getById(gatewayId);
            try{
                if(gdevice.getIsDoor() == 1 || gdevice.getIsVoice() == 1){
                    continue;
                }
                else{
                    operateGatewayDeivce(gdevice,gatewayInfo,1);
                }
            }catch (Exception e){
                log.error("关闭网关设备失败.异常:{}",e.getMessage());
                return new CommonResult().failed("关闭网关设备失败");
            }
        }
        return new CommonResult().success();
    }


    private void operateGatewayDeivce(QsgGatewayDevice gatewayDevice, QsgGatewayInfo gatewayInfo, int type) throws Exception {
        JSONObject data = new JSONObject();
        data.put("CommandId", UUID.randomUUID().toString());
        data.put("SystemCode", "csqsg");
        data.put("GatewayIeee", gatewayInfo.getSerialno());
        data.put("SensorIeee", gatewayDevice.getIeeeEpAddr());
        if (type == 0) {
            data.put("Command", "On");
        } else {
            data.put("Command", "Off");
        }
        mqttConfigService.publish("/toGW/" + gatewayInfo.getMacAddr(), data.toJSONString());
        log.info("发送mqtt消息给设备:{}成功.", gatewayDevice.getIeeeEpAddr());
    }


    private void operateGatewayLock(QsgGatewayDevice gatewayDevice, QsgGatewayInfo gatewayInfo, int type) throws Exception {
        JSONObject data = new JSONObject();
        data.put("CommandId", UUID.randomUUID().toString());
        data.put("SystemCode", "csqsg");
        data.put("GatewayIeee", gatewayInfo.getSerialno());
        data.put("SensorIeee", gatewayDevice.getIeeeEpAddr());
        if (type == 0) {
            data.put("Command", "UnlockDoor");
        } else {
            data.put("Command", "LockDoor");
        }
        data.put("PINCode", "1809598");
        mqttConfigService.publish("/toGW/" + gatewayInfo.getMacAddr(), data.toJSONString());
        log.info("发送mqtt消息给设备:{}成功.", gatewayDevice.getIeeeEpAddr());
    }

    private void sendWifiLockMsg(QsgDevice device) {
        HttpClientUtil clientUtil = HttpClientUtil.getInstance();
        Map<String, String> params = new HashMap<>();
        Map<String, String> headMap = new HashMap<>();
        //deviceId为wifi锁的编号
        params.put("deviceId", device.getDeviceCode());
        headMap.put("Authorization", device.getToken());
        String u = clientUtil.httpPost(LockInfo.OPEN_DOOR, params, headMap);
        JSONObject result = JSON.parseObject(u);
        if (200 == result.getIntValue("code")) {
            log.info("打开wifi锁:{}成功.", device.getDeviceCode());
        }
    }
}
